<?php
/*
 * user model
 * 
 */
class User extends AppModel {
	var $name = "User";
	var $hasOne = array(
		'Profile' => array(
			'className' => 'Profile',
			'foreignKey' => 'user_id',
			'conditions' => array('Profile.del_flg' => 0),
			'dependent' => true //when delete user, will delete his profile
		)
	);
	var $validate = array(
		'password' => array(
			'alphaNumeric' => array(
				'rule' => 'alphaNumeric',
				'required' => true,
				'allowEmpty' => false,
				'message' => Messages::password_repeat_must_be_alphabet_or_numeric
			),
			'minLength' => array(
				'rule' => array('minLength', 6),
				'message' => Messages::password_length_must_be_longer_than_6_characters
			)
		),
		'email' => array(
			'email' => array(
				'rule' => 'email',
				'required' => true,
				'message' => Messages::invalid_email_address
			),
			'isUnique' => array(
				'rule' => 'isUnique',
				'message' => Messages::email_has_been_existed
			)
		),

	);

	
	/**
	 * Generate random password
	 *
	 * @return string
	 */
	function generatePassword() {
		return uniqid();
	}

	/**
	 * Get top users
	 *
	 * @param $limit - Number of users will be returned
	 * @return mixed
	 */
	function getTopUser($limit = 5) {
		$options = array(
			'recursive' => 0,
			'limit' => $limit,
			'joins' => array(
				array(
					'table' => 'recommend_teachers',
					'alias' => 'RecommendTeachers',
					'type' => 'inner',
					'conditions' => array(
						'User.id = RecommendTeachers.user_id',
						'User.del_flg = 0'
					)
				)
			),
			'order' => 'RecommendTeachers.rank ASC',
		);

		return $this->find('all', $options);
	}

	/**
	 * Add point for user, base on money user spent
	 *
	 * @param $userId
	 * @param $amount
	 * @param $ratio
	 */
	function addPoint($userId, $amount, $ratio) {
		if ($ratio == 0) {
			$ratio = 1;
		}
		$point = floor($amount / $ratio);
		$update = array(
			'now_point' => 'now_point + ' . $point,
			'max_point' => 'max_point + ' . $point,
		);
		$this->recursive = -1;
		$this->updateAll(
			$update,
			array($this->alias . '.id' => $userId)
		);
	}

	/**
	 * Remove point of user, base on the money return to user
	 *
	 * @param $userId
	 * @param $amount
	 * @param $ratio
	 */
	function removePoint($userId, $amount, $ratio) {
		if ($ratio == 0) {
			$ratio = 1;
		}
		$point = floor($amount / $ratio);
		$update = array(
			'now_point' => 'now_point - ' . $point,
			'max_point' => 'max_point - ' . $point,
		);
		$this->recursive = -1;
		$this->updateAll(
			$update,
			array($this->alias . '.id' => $userId)
		);
	}

	/**
	 * Get user joined to a course
	 *
	 * @param $courseId
	 * @return array
	 */
	function getUserJoinedCourse($courseId) {
		$subQuery = 'SELECT ec.user_id
				FROM entered_courses ec
					INNER JOIN courses_detail cd ON cd.id = ec.detail_id
					INNER JOIN courses c ON cd.course_id = c.id
				WHERE cd.course_id = '. intval($courseId) . ' AND ec.del_flg = 0 AND cd.del_flg = 0';
		$options = array(
			'fields' => array(
				'User.*',
				'Profile.*',
			),
			'conditions' => array(
				'User.id IN ('.$subQuery.')',
			)
		);

		return $this->find('all', $options);
	}

	/**
	 * Get user by it's id
	 *
	 * @param $userId
	 * @return array
	 */
	function getById ($userId) {
		$options = array(
			'fields' => array(
				'User.*',
				'Profile.*',
			),
			'conditions' => array(
				'User.id' => $userId,
			),
			'joins' => array(
				array(
					'table' => 'profiles',
					'alias' => 'Profile',
					'type' => 'LEFT',
					'conditions' => array(
						$this->alias . '.id = Profile.user_id AND Profile.del_flg = 0',
					)
				)
			)
		);

		return $this->find('first', $options);
	}

	/**
	 * Get users are watching this user
	 *
	 * @param $userId
	 * @return array
	 *
	 */
	function getWatchList ($userId) {
		$options = array(
			'conditions' => array(
				$this->alias . '.id IN (SELECT tw.user_id FROM target_of_watch tw WHERE tw.watch_id = ' . intval($userId) .')',
				$this->alias . '.del_flg' => 0,
			),
		);
		return $this->find('all', $options);
	}
	
	/**
	 * get value of one field
	 * @param string $field
	 * @param int $userId
	 * @return type
	 */
	function getField($field, $userId) {
		return $this->field($field, array(
			$this->alias . '.id' => $userId
		));
	}
	
	/**
	 * delete all data of user ( be deleted by admin)
	 * @param int $userId
	 * @return boolean
	 */
	function deleteAllDataOfUser($userId) {
		App::import('model', 'Profile');
		App::import('model', 'BankInformation');
		App::import('model', 'Comment');
		App::import('model', 'Review');
		App::import('model', 'Course');
		App::import('model', 'CourseDetail');
		App::import('model', 'EnteredCourse');
		App::import('model', 'Transaction');
		
		$profile = new Profile();
		$bankInfo = new BankInformation();
		$transaction = new Transaction();
		$comment = new Comment();
		$review = new Review();
		$dataSource = $this->getDataSource();
		$dataSource->begin($this);
		if(!$this->deleteDataById($userId)){
			$dataSource->rollback($this);
			return false;
		}
		if(!$profile->deleteDataByKey('user_id', $userId)){
			$dataSource->rollback($this);
			return false;
		}
		if(!$bankInfo->deleteDataByKey('user_id', $userId)){
			$dataSource->rollback($this);
			return false;
		}
		
		//delete transaction
		if(!$transaction->deleteDataByKey('user_id', $userId)){
			$dataSource->rollback($this);
			return false;
		}
		
		//delete entered_course
		$enteredCourse = new EnteredCourse();
		if(!$enteredCourse->deleteDataByKey('user_id', $userId)){
			$dataSource->rollback($this);
			return false;
		}
		//delete course, course Detail
		$course = new Course();
		$courseDetail = new CourseDetail();
		$courses = $course->find('all', array(
			'fields' => array('id'),
			'conditions' => array(
			 	$course->alias . '.user_id' => $userId,
				$course->alias . '.del_flg' => 0
			)
		));
		foreach ($courses as $key => $value) {
			if(!$courseDetail->deleteDataByKey('course_id', $value[$course->alias]['id'])){
				$dataSource->rollback($this);
				return false;
			}
		}
		if(!$course->deleteDataByKey('user_id', $userId)){
			$dataSource->rollback($this);
			return false;
		}
		
		//delete review
		if(!$review->deleteDataByKey('user_id', $userId)){
			$dataSource->rollback($this);
			return false;
		}
		// delete comment
		$comments = $comment->getAllCommentOfUser($userId);
		foreach ($comments as $key => $value) {
			if($value['Comment']['comment_id'] == 0){
				$comment->deleteCommentById($value['Comment']['id'], $userId);//check transaction in Comment model ??
			}else{
				$parrent = '';
				$comment->deleteReplyById($value['Comment']['id'], $userId, $parrent);
			}
		}
		
		$dataSource->commit($this);
		return true;
	}

	/**
	 * Get total user in the site
	 * @return integer
	 */
	function getTotalUser() {
		$options = array(
			'conditions' => array(
				$this->alias . '.del_flg' => 0,
			)
		);

		return $this->find('count', $options);
	}

	/**
	 * Get total user active
	 * @return integer
	 */
	function getTotalActiveUser() {
		$options = array(
			'recursive' => -1,
			'conditions' => array(
				$this->alias . '.id IN (SELECT ec.user_id FROM entered_courses ec WHERE ec.del_flg = 0)'
			)
		);
		$nbJoinedCourse = $this->find('count', $options);

		$options = array(
			'recursive' => -1,
			'conditions' => array(
				$this->alias .'.id IN (SELECT c.user_id FROM courses c WHERE c.del_flg = 0)'
			)
		);
		$nbCreatedCourse = $this->find('count', $options);

		return $nbCreatedCourse + $nbJoinedCourse;
	}
	
	/**
	 * 
	 * @param int $userId
	 * @return boolean
	 */
	function isValidUser($userId) {
		$count = $this->find('count', array(
			'conditions' => array(
				$this->alias . '.id' => $userId,
				$this->alias . '.del_flg' => 0
			)
		));
		if($count > 0){
			return true;
		}
		return false;
	}

	function getProfileExport() {
		$options = array(
			'fields' => array(
				$this->alias . '.*',
				$this->Profile->alias . '.*',
			)
		);

		$users = $this->find('all', $options);
		$data = array();
		foreach ($users as $user) {
			$data[] = array(
				$user['User']['id'],
				$user['User']['email'],
				$user['Profile']['first_name'],
				$user['Profile']['last_name'],
				$user['Profile']['headline'],
				$user['Profile']['description'],
				$user['User']['mailmagazine_flg'],
				$user['User']['mail_wishlist_flg'],
				$user['User']['profile_setting'],
				$user['User']['now_point'],
				$user['User']['max_point'],
				$user['User']['created'],
				$user['User']['role'],
				$user['User']['del_flg'],
			);
		}

		return $data;
	}
}
